package polsl.biai.projekt.server.calculation;

import java.util.ArrayList;

/**
 * Tour contains list of Cities
 * @author jacek
 *
 */
public class Tour {

	/**
	 * list of the cities in tour
	 */
    private ArrayList<City> tour = new ArrayList<City>();
    
    /**
     * tour's distance
     */
    private int distance = 0;
    
    /**
     * constructor
     * makes a new, empty tour
     */
    public Tour(){
        for (int i = 0; i < CityList.numberOfCities(); i++) {
            tour.add(null);
        }
    }
    
    /**
     * constructor
     * makes a tour from list of the cities
     * @param tour list of the cities
     */
    public Tour(ArrayList<City> tour){
        this.tour = tour;
    }
    
    /**
     * swaps two cities in tour
     * @param idx1 index of 1st City
     * @param idx2 index of 2nd City
     */
    public void swapCities(int idx1, int idx2) {
        City o1 = tour.get(idx1);
        tour.set(idx1, tour.get(idx2));
        tour.set(idx2, o1);
    }

    /**
     * shuffles cities in tour to get new, random tour
     */
    public void shuffle() {
        for(int i = tour.size()-1; i >=0; i--) 
        {
                int j = (int) Math.random();
                
                City o1 = tour.get(i);
                tour.set(i, tour.get(j));
                tour.set(j, o1);
        }
    }
    
        
    /**
     * gets cities from CityList and adds them to the tour
     * shuffles the new tour to get random tour
     */
    public void generateRandomTour() {
        for (int i = 0; i < CityList.numberOfCities(); i++) {
          addCity(i, CityList.getCity(i));
        }
        shuffle();               
    }

   /**
    * gets City from the tour
    * @param tourPosition
    * @return City
    */
    public City getCity(int tourPosition) {
        return (City)tour.get(tourPosition);
    }

    
    /**
     * adds City to the tour
     * sets distance to 0 
     * @param tourPosition
     * @param city
     */
    public void addCity(int tourPosition, City city) {
        tour.set(tourPosition, city);
        distance = 0;
    }   

    
    /**
     * calculates tour's distance 
     * @return
     */
    public int getDistance(){
        if (distance == 0) {
            int tourDistance = 0;
            for (int i=0; i < tourSize(); i++) {
            	
                City fromCity = getCity(i);
                City destinationCity;

                /**
                 * checks if the current City is last in the list
                 * if it is next City is 1st City
                 */
                if(i+1 < tourSize()){
                    destinationCity = getCity(i+1);
                }
                else{
                    destinationCity = getCity(0);
                }
              
                /**
                 * gets distance between two Cities
                 */
                tourDistance += fromCity.getDistance(destinationCity);
            }
            distance = tourDistance;
        }
        return distance;
    }

    public int tourSize() {
        return tour.size();
    }
    
    /**
     * checks if the tour contains City 
     * @param city
     * @return
     */
    public boolean containsCity(City city){
        return tour.contains(city);
    }
    
    /**
     * generates String from the tour
     * Cities are divided by #
     */
    @Override
    public String toString() {
        String tourString = "#";
        for (int i = 0; i < tourSize(); i++) {
            tourString += getCity(i).getName()+"#";
        }
        return tourString;
    }
    
    /**
     * returns tour
     * @return
     */
    public ArrayList<City> getTour()
    {
    	return tour;
    }
}
